/*
 * WindowController.cpp
 *
 *  Created on: 06/11/2012
 *      Author: san
 */

#include "WindowController.h"
#include "DropButton.h"
#include "Caja.h"
#include <list>
#include <iostream>
WindowController::WindowController(Gtk::Window *window, ButtonPanelController *dpc, LevelView *lv, ButtonPanelController *tpc, Gtk::Statusbar *statusbar) : window(window), dpc(dpc), lv(lv), tpc(tpc), statusbar(statusbar), state(NONE) {
	// Tool panel
	this->tpc->addButton("eliminar.jpeg");
	this->tpc->getAllButtons().front()->signal_clicked().connect(sigc::mem_fun(*this, &WindowController::onRemoveButtonClick));

	// Drop panel
	this->dpc->addButton("cajaButton.png");
	this->dpc->addButton("chanchoButton.jpg");

	std::list<DropButton *> buttonList = this->dpc->getAllButtons();
	std::list<DropButton *>::iterator i = buttonList.begin();
	(*i)->signal_clicked().connect(sigc::mem_fun(*this, &WindowController::onCajaButtonClick));
	++i;
	(*i)->signal_clicked().connect(sigc::mem_fun(*this, &WindowController::onCerditoButtonClick));

	// Level
	this->lv->setBackground("background.jpg");
	this->lv->signal_button_press_event().connect(sigc::mem_fun(*this, &WindowController::onLevelClick));

	// Window Setting
	this->changeState(NONE);
}

WindowController::~WindowController() {
	std::list<Dibujable *>::iterator i = this->dibujables.begin();
	while (i != this->dibujables.end()) {
		delete *i;
		++i;
	}
}

void WindowController::onRemoveButtonClick() {
	if (this->state != NONE)
			return;
	this->changeState(REMOVESTATE);
}

void WindowController::onCajaButtonClick() {
	if (this->state != NONE)
		return;

	Caja *caja = new Caja();
	caja->setImagePath("cajaButton.png");
	this->nivel.agregar(*caja);

	this->dibujables.push_back(caja);
	this->selected = caja;
	this->changeState(ADDSTATE);
}

void WindowController::onCerditoButtonClick() {
	if (this->state != NONE)
		return;

	Caja *caja = new Caja();
	caja->setImagePath("chanchoButton.jpg");
	this->nivel.agregar(*caja);

	this->dibujables.push_back(caja);
	this->selected = caja;
	this->changeState(ADDSTATE);
}

bool WindowController::onLevelClick(GdkEventButton *button) {
	switch (this->state) {
	case NONE:
		return true;
	case ADDSTATE:
		this->selected->setPosicionX(button->x);
		this->selected->setPosicionY(button->y);
		this->refreshScreen();
		this->changeState(NONE);
		break;
	case MOVESTATE:
		this->selected->setPosicionX(button->x);
		this->selected->setPosicionY(button->y);
		this->refreshScreen();
		this->changeState(NONE);
		break;
	default:
		break;
	}
	return true;
}

bool WindowController::onDropClick(GdkEventButton *button, Drop *drop) {
	switch (this->state) {
	case NONE:
		this->selected = drop->getDibujable();
		this->changeState(MOVESTATE);
		return true;
	case REMOVESTATE:
		this->nivel.remover(*drop->getDibujable());
		this->dibujables.remove(drop->getDibujable());
		delete drop->getDibujable();
		this->refreshScreen();
		this->changeState(NONE);
		break;
	default:
		break;
	}

	return true;
}

void WindowController::refreshScreen() {
	std::vector<Dibujable *> showVector;
	std::list<Dibujable *>::iterator lIt = this->nivel.getElementos().begin();
	while (lIt != this->nivel.getElementos().end()) {
		showVector.push_back(*lIt);
		++lIt;
	}

	this->lv->show(showVector);

	std::list<Drop *>::iterator dIt = this->lv->getDrops().begin();
	while (dIt != this->lv->getDrops().end()) {
		(*dIt)->signal_button_press_event().connect(sigc::bind<Drop *>(sigc::mem_fun(*this, &WindowController::onDropClick), *dIt));
		++dIt;
	}
}

void WindowController::changeState(State state) {
	this->state = state;
	this->statusbar->pop();
	switch (this->state) {
	case NONE:
		this->statusbar->push("Idle.");
		break;
	case MOVESTATE:
		this->statusbar->push("Moving element...");
		break;
	case ADDSTATE:
		this->statusbar->push("Adding element...");
		break;
	case REMOVESTATE:
		this->statusbar->push("Removing element...");
		break;
	default:
		this->statusbar->push("Idle.");
		break;
	}
}
